package ca.camosun.proximity.tests;

import static org.junit.Assert.*;

import java.util.Iterator;

import org.junit.Before;
import org.junit.Test;

import ca.camosun.proximity.DeviceTracker;
import ca.camosun.proximity.Room;
import ca.camosun.proximity.SavedPerson;


public class RoomTest {
	SavedPerson userA;
	SavedPerson userB;
	SavedPerson userC;
	
	SavedPerson userD;
	SavedPerson userE;
	SavedPerson userF;
	
	Room aRoom;

	@Before
	public void setUp() throws Exception {
		
		userA = new SavedPerson("a", "addr1");
		userB = new SavedPerson("b", "addr2");
		userC = new SavedPerson("c", "addr3");
		
		userD = new SavedPerson("d", "addr1");
		userE = new SavedPerson("e", "addr2");
		userF = new SavedPerson("f", "addr3");
		
		aRoom = Room.getInstance();
		
	}
	
	@Test
	public void onePersonEntersRoom() {
		
		aRoom.foundADevice(userA);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 1);
		assertTrue(aRoom.contains(userA));
	}
	
	@Test
	public void onePersonEntersAndLeavesRoom() {
		
		aRoom.foundADevice(userB);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 1);
		assertTrue(aRoom.contains(userB));
		
		aRoom.userLeavesRoom(userB);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 0);
		assertTrue(aRoom.contains(userB) == false);
		
	}
	
	@Test
    public void multiplePeopleEnter(){
		
		aRoom.foundADevice(userA);
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 3);
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
	}
	
	@Test
    public void multipleEnterAndOneLeaves(){ 	
		
		aRoom.foundADevice(userA);
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 3);
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
		aRoom.userLeavesRoom(userA);
		
		DeviceTracker departure = new DeviceTracker("departure");
		departure.addDevice(userA);
		DeviceTracker aRoomsDepartures = aRoom.getDepartures();
		
		assertTrue(departure.getDeviceByIndex(0).equals(aRoomsDepartures.getDeviceByIndex(0)));
		
		assertTrue(aRoom.getDepartures().deviceCount() == 1);
		assertTrue(aRoom.howManyPeopleAreInRoom() == 2);
	}
	
	@Test
    public void multipleEnterAndTwoLeaves(){	

		aRoom.foundADevice(userA);
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 3);
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
		aRoom.userLeavesRoom(userA);
		aRoom.userLeavesRoom(userB);
		
		DeviceTracker departure = new DeviceTracker("departure");
		departure.addDevice(userA);
		departure.addDevice(userB);
		DeviceTracker aRoomsDepartures = aRoom.getDepartures();
		
		Iterator<SavedPerson> aRoomsIterator = aRoomsDepartures.iterator();
		Iterator<SavedPerson> departureIterator = departure.iterator();
		
		while (aRoomsIterator.hasNext() | departureIterator.hasNext() == true){
			assertTrue(aRoomsIterator.next().equals(departureIterator.next()));
		}
		
		assertTrue(aRoom.getDepartures().deviceCount() ==2);
		assertTrue(aRoom.howManyPeopleAreInRoom() == 1);
	}
	
	@Test
    public void multipleEnterAndLeave(){ 	

		aRoom.foundADevice(userA);
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.howManyPeopleAreInRoom() == 3);
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
		aRoom.userLeavesRoom(userA);
		aRoom.userLeavesRoom(userB);
		aRoom.userLeavesRoom(userC);
		
		DeviceTracker departure = new DeviceTracker("departure");
		departure.addDevice(userA);
		departure.addDevice(userB);
		departure.addDevice(userC);
		DeviceTracker aRoomsDepartures = aRoom.getDepartures();
		
		Iterator<SavedPerson> aRoomsIterator = aRoomsDepartures.iterator();
		Iterator<SavedPerson> departureIterator = departure.iterator();
		
		while (aRoomsIterator.hasNext() | departureIterator.hasNext() == true){
			assertTrue(aRoomsIterator.next().equals(departureIterator.next()));
		}
		
		assertTrue(aRoom.getDepartures().deviceCount() == 3);
		assertTrue(aRoom.howManyPeopleAreInRoom() == 0);
	}
	
	@Test
	public void didPersonOfInterestLeave(){
		
		aRoom.foundADevice(userA);
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
		aRoom.keepPersonClose(userA);
		assertTrue(aRoom.isPersonStillNear(userA));
		
		aRoom.userLeavesRoom(userA);
		
		assertTrue(aRoom.getDepartures().deviceCount() == 1);
		assertTrue(aRoom.isPersonStillNear(userA) == false);
	}
	
	@Test
	public void didPersonOfInterestEnter(){
		
		aRoom.foundADevice(userB);
		aRoom.foundADevice(userC);
		
		assertTrue(aRoom.contains(userB));
		assertTrue(aRoom.contains(userC));
		
		aRoom.keepPersonAway(userA);
		assertTrue(aRoom.isPersonStillAway(userA));
		
		aRoom.foundADevice(userA);
		assertTrue(aRoom.contains(userA));
		assertTrue(aRoom.isPersonStillAway(userA) == false);
	}
}

